home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / zgstate.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  12.5 KB  |  546 lines

  1. /* Copyright (C) 1989, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: zgstate.c,v 1.2 2000/09/19 19:00:54 lpd Exp $ */
  20. /* Graphics state operators */
  21. #include "math_.h"
  22. #include "ghost.h"
  23. #include "oper.h"
  24. #include "ialloc.h"
  25. #include "icremap.h"
  26. #include "idict.h"
  27. #include "istruct.h"
  28. #include "igstate.h"
  29. #include "gsmatrix.h"
  30. #include "store.h"
  31.  
  32. /* Structure descriptors */
  33. private_st_int_gstate();
  34. private_st_int_remap_color_info();
  35.  
  36. /* ------ Utilities ------ */
  37.  
  38. private int
  39. zset_real(i_ctx_t *i_ctx_p, int (*set_proc)(P2(gs_state *, floatp)))
  40. {
  41.     os_ptr op = osp;
  42.     double param;
  43.     int code = real_param(op, ¶m);
  44.  
  45.     if (code < 0)
  46.     return_op_typecheck(op);
  47.     code = set_proc(igs, param);
  48.     if (!code)
  49.     pop(1);
  50.     return code;
  51. }
  52.  
  53. private int
  54. zset_bool(i_ctx_t *i_ctx_p, void (*set_proc)(P2(gs_state *, bool)))
  55. {
  56.     os_ptr op = osp;
  57.  
  58.     check_type(*op, t_boolean);
  59.     set_proc(igs, op->value.boolval);
  60.     pop(1);
  61.     return 0;
  62. }
  63.  
  64. private int
  65. zcurrent_bool(i_ctx_t *i_ctx_p, bool (*current_proc)(P1(const gs_state *)))
  66. {
  67.     os_ptr op = osp;
  68.  
  69.     push(1);
  70.     make_bool(op, current_proc(igs));
  71.     return 0;
  72. }
  73.  
  74. /* ------ Operations on the entire graphics state ------ */
  75.  
  76. /* "Client" procedures */
  77. private void *gs_istate_alloc(P1(gs_memory_t * mem));
  78. private int gs_istate_copy(P2(void *to, const void *from));
  79. private void gs_istate_free(P2(void *old, gs_memory_t * mem));
  80. private const gs_state_client_procs istate_procs = {
  81.     gs_istate_alloc,
  82.     gs_istate_copy,
  83.     gs_istate_free
  84. };
  85.  
  86. /* Initialize the graphics stack. */
  87. gs_state *
  88. int_gstate_alloc(const gs_dual_memory_t * dmem)
  89. {
  90.     int_gstate *iigs;
  91.     ref proc0;
  92.     int_remap_color_info_t *prci;
  93.     gs_ref_memory_t *lmem = dmem->space_local;
  94.     gs_ref_memory_t *gmem = dmem->space_global;
  95.     gs_state *pgs = gs_state_alloc((gs_memory_t *)lmem);
  96.  
  97.     iigs = gs_alloc_struct((gs_memory_t *)lmem, int_gstate, &st_int_gstate,
  98.                "int_gstate_alloc(int_gstate)");
  99.     int_gstate_map_refs(iigs, make_null);
  100.     make_empty_array(&iigs->dash_pattern, a_all);
  101.     gs_alloc_ref_array(lmem, &proc0, a_readonly + a_executable, 2,
  102.                "int_gstate_alloc(proc0)");
  103.     make_oper(proc0.value.refs, 0, zpop);
  104.     make_real(proc0.value.refs + 1, 0.0);
  105.     iigs->black_generation = proc0;
  106.     iigs->undercolor_removal = proc0;
  107.     /*
  108.      * Even though the gstate itself is allocated in local VM, the
  109.      * container for the color remapping procedure must be allocated in
  110.      * global VM so that the gstate can be copied into global VM.
  111.      */
  112.     prci = gs_alloc_struct((gs_memory_t *)gmem, int_remap_color_info_t,
  113.                &st_int_remap_color_info,
  114.                "int_gstate_alloc(remap color info)");
  115.     make_struct(&iigs->remap_color_info, imemory_space(gmem), prci);
  116.     clear_pagedevice(iigs);
  117.     gs_state_set_client(pgs, iigs, &istate_procs);
  118.     /* PostScript code wants limit clamping enabled. */
  119.     gs_setlimitclamp(pgs, true);
  120.     /*
  121.      * gsave and grestore only work properly
  122.      * if there are always at least 2 entries on the stack.
  123.      * We count on the PostScript initialization code to do a gsave.
  124.      */
  125.     return pgs;
  126. }
  127.  
  128. /* - gsave - */
  129. int
  130. zgsave(i_ctx_t *i_ctx_p)
  131. {
  132.     return gs_gsave(igs);
  133. }
  134.  
  135. /* - grestore - */
  136. int
  137. zgrestore(i_ctx_t *i_ctx_p)
  138. {
  139.     return gs_grestore(igs);
  140. }
  141.  
  142. /* - grestoreall - */
  143. int
  144. zgrestoreall(i_ctx_t *i_ctx_p)
  145. {
  146.     return gs_grestoreall(igs);
  147. }
  148.  
  149. /* - initgraphics - */
  150. private int
  151. zinitgraphics(i_ctx_t *i_ctx_p)
  152. {
  153.     /* gs_initgraphics does a setgray; we must clear the interpreter's */
  154.     /* cached copy of the color space object. */
  155.     int code = gs_initgraphics(igs);
  156.  
  157.     if (code >= 0)
  158.     make_null(&istate->colorspace.array);
  159.     return code;
  160. }
  161.  
  162. /* ------ Operations on graphics state elements ------ */
  163.  
  164. /* <num> setlinewidth - */
  165. private int
  166. zsetlinewidth(i_ctx_t *i_ctx_p)
  167. {
  168.     os_ptr op = osp;
  169.     /*
  170.      * The Red Book doesn't say anything about this, but Adobe
  171.      * interpreters return (or perhaps store) the absolute value
  172.      * of the width.
  173.      */
  174.     double width;
  175.     int code = real_param(op, &width);
  176.  
  177.     if (code < 0)
  178.     return_op_typecheck(op);
  179.     code = gs_setlinewidth(igs, fabs(width));
  180.     if (code >= 0)
  181.     pop(1);
  182.     return code;
  183. }
  184.  
  185. /* - currentlinewidth <num> */
  186. private int
  187. zcurrentlinewidth(i_ctx_t *i_ctx_p)
  188. {
  189.     os_ptr op = osp;
  190.  
  191.     push(1);
  192.     make_real(op, gs_currentlinewidth(igs));
  193.     return 0;
  194. }
  195.  
  196. /* <cap_int> .setlinecap - */
  197. private int
  198. zsetlinecap(i_ctx_t *i_ctx_p)
  199. {
  200.     os_ptr op = osp;
  201.     int param;
  202.     int code = int_param(op, max_int, ¶m);
  203.  
  204.     if (code < 0 || (code = gs_setlinecap(igs, (gs_line_cap) param)) < 0)
  205.     return code;
  206.     pop(1);
  207.     return 0;
  208. }
  209.  
  210. /* - currentlinecap <cap_int> */
  211. private int
  212. zcurrentlinecap(i_ctx_t *i_ctx_p)
  213. {
  214.     os_ptr op = osp;
  215.  
  216.     push(1);
  217.     make_int(op, (int)gs_currentlinecap(igs));
  218.     return 0;
  219. }
  220.  
  221. /* <join_int> .setlinejoin - */
  222. private int
  223. zsetlinejoin(i_ctx_t *i_ctx_p)
  224. {
  225.     os_ptr op = osp;
  226.     int param;
  227.     int code = int_param(op, max_int, ¶m);
  228.  
  229.     if (code < 0 || (code = gs_setlinejoin(igs, (gs_line_join) param)) < 0)
  230.     return code;
  231.     pop(1);
  232.     return 0;
  233. }
  234.  
  235. /* - currentlinejoin <join_int> */
  236. private int
  237. zcurrentlinejoin(i_ctx_t *i_ctx_p)
  238. {
  239.     os_ptr op = osp;
  240.  
  241.     push(1);
  242.     make_int(op, (int)gs_currentlinejoin(igs));
  243.     return 0;
  244. }
  245.  
  246. /* <num> setmiterlimit - */
  247. private int
  248. zsetmiterlimit(i_ctx_t *i_ctx_p)
  249. {
  250.     return zset_real(i_ctx_p, gs_setmiterlimit);
  251. }
  252.  
  253. /* - currentmiterlimit <num> */
  254. private int
  255. zcurrentmiterlimit(i_ctx_t *i_ctx_p)
  256. {
  257.     os_ptr op = osp;
  258.  
  259.     push(1);
  260.     make_real(op, gs_currentmiterlimit(igs));
  261.     return 0;
  262. }
  263.  
  264. /* <array> <offset> setdash - */
  265. private int
  266. zsetdash(i_ctx_t *i_ctx_p)
  267. {
  268.     os_ptr op = osp;
  269.     os_ptr op1 = op - 1;
  270.     double offset;
  271.     int code = real_param(op, &offset);
  272.     uint i, n;
  273.     gs_memory_t *mem = imemory;
  274.     float *pattern;
  275.  
  276.     if (code < 0)
  277.     return_op_typecheck(op);
  278.     if (!r_is_array(op1))
  279.     return_op_typecheck(op1);
  280.     /* Adobe interpreters apparently don't check the array for */
  281.     /* read access, so we won't either. */
  282.     /*check_read(*op1); */
  283.     /* Unpack the dash pattern and check it */
  284.     n = r_size(op1);
  285.     pattern =
  286.     (float *)gs_alloc_byte_array(mem, n, sizeof(float), "setdash");
  287.  
  288.     if (pattern == 0)
  289.     return_error(e_VMerror);
  290.     for (i = 0, code = 0; i < n && code >= 0; ++i) {
  291.     ref element;
  292.  
  293.     array_get(op1, (long)i, &element);
  294.     code = float_param(&element, &pattern[i]);
  295.     }
  296.     if (code >= 0)
  297.     code = gs_setdash(igs, pattern, n, offset);
  298.     gs_free_object(mem, pattern, "setdash");    /* gs_setdash copies this */
  299.     if (code < 0)
  300.     return code;
  301.     ref_assign(&istate->dash_pattern, op1);
  302.     pop(2);
  303.     return code;
  304. }
  305.  
  306. /* - currentdash <array> <offset> */
  307. private int
  308. zcurrentdash(i_ctx_t *i_ctx_p)
  309. {
  310.     os_ptr op = osp;
  311.  
  312.     push(2);
  313.     ref_assign(op - 1, &istate->dash_pattern);
  314.     make_real(op, gs_currentdash_offset(igs));
  315.     return 0;
  316. }
  317.  
  318. /* <num> setflat - */
  319. private int
  320. zsetflat(i_ctx_t *i_ctx_p)
  321. {
  322.     return zset_real(i_ctx_p, gs_setflat);
  323. }
  324.  
  325. /* - currentflat <num> */
  326. private int
  327. zcurrentflat(i_ctx_t *i_ctx_p)
  328. {
  329.     os_ptr op = osp;
  330.  
  331.     push(1);
  332.     make_real(op, gs_currentflat(igs));
  333.     return 0;
  334. }
  335.  
  336. /* ------ Extensions ------ */
  337.  
  338. /* <bool> .setaccuratecurves - */
  339. private int
  340. zsetaccuratecurves(i_ctx_t *i_ctx_p)
  341. {
  342.     return zset_bool(i_ctx_p, gs_setaccuratecurves);
  343. }
  344.  
  345. /* - .currentaccuratecurves <bool> */
  346. private int
  347. zcurrentaccuratecurves(i_ctx_t *i_ctx_p)
  348. {
  349.     return zcurrent_bool(i_ctx_p, gs_currentaccuratecurves);
  350. }
  351.  
  352. /* <join_int|-1> .setcurvejoin - */
  353. private int
  354. zsetcurvejoin(i_ctx_t *i_ctx_p)
  355. {
  356.     os_ptr op = osp;
  357.     int code;
  358.  
  359.     check_type(*op, t_integer);
  360.     if (op->value.intval < -1 || op->value.intval > max_int)
  361.     return_error(e_rangecheck);
  362.     code = gs_setcurvejoin(igs, (int)op->value.intval);
  363.     if (code < 0)
  364.     return code;
  365.     pop(1);
  366.     return 0;
  367. }
  368.  
  369. /* - .currentcurvejoin <join_int|-1> */
  370. private int
  371. zcurrentcurvejoin(i_ctx_t *i_ctx_p)
  372. {
  373.     os_ptr op = osp;
  374.  
  375.     push(1);
  376.     make_int(op, gs_currentcurvejoin(igs));
  377.     return 0;
  378. }
  379.  
  380. /* <adjust.x> <adjust.y> .setfilladjust2 - */
  381. private int
  382. zsetfilladjust2(i_ctx_t *i_ctx_p)
  383. {
  384.     os_ptr op = osp;
  385.     double adjust[2];
  386.     int code = num_params(op, 2, adjust);
  387.  
  388.     if (code < 0)
  389.     return code;
  390.     code = gs_setfilladjust(igs, adjust[0], adjust[1]);
  391.     if (code < 0)
  392.     return code;
  393.     pop(2);
  394.     return 0;
  395. }
  396.  
  397. /* - .currentfilladjust2 <adjust.x> <adjust.y> */
  398. private int
  399. zcurrentfilladjust2(i_ctx_t *i_ctx_p)
  400. {
  401.     os_ptr op = osp;
  402.     gs_point adjust;
  403.  
  404.     push(2);
  405.     gs_currentfilladjust(igs, &adjust);
  406.     make_real(op - 1, adjust.x);
  407.     make_real(op, adjust.y);
  408.     return 0;
  409. }
  410.  
  411. /* <bool> .setdashadapt - */
  412. private int
  413. zsetdashadapt(i_ctx_t *i_ctx_p)
  414. {
  415.     return zset_bool(i_ctx_p, gs_setdashadapt);
  416. }
  417.  
  418. /* - .currentdashadapt <bool> */
  419. private int
  420. zcurrentdashadapt(i_ctx_t *i_ctx_p)
  421. {
  422.     return zcurrent_bool(i_ctx_p, gs_currentdashadapt);
  423. }
  424.  
  425. /* <num> <bool> .setdotlength - */
  426. private int
  427. zsetdotlength(i_ctx_t *i_ctx_p)
  428. {
  429.     os_ptr op = osp;
  430.     double length;
  431.     int code = real_param(op - 1, &length);
  432.  
  433.     if (code < 0)
  434.     return code;
  435.     check_type(*op, t_boolean);
  436.     code = gs_setdotlength(igs, length, op->value.boolval);
  437.     if (code < 0)
  438.     return code;
  439.     pop(2);
  440.     return 0;
  441. }
  442.  
  443. /* - .currentdotlength <num> <bool> */
  444. private int
  445. zcurrentdotlength(i_ctx_t *i_ctx_p)
  446. {
  447.     os_ptr op = osp;
  448.  
  449.     push(2);
  450.     make_real(op - 1, gs_currentdotlength(igs));
  451.     make_bool(op, gs_currentdotlength_absolute(igs));
  452.     return 0;
  453. }
  454.  
  455. /* - .setdotorientation - */
  456. private int
  457. zsetdotorientation(i_ctx_t *i_ctx_p)
  458. {
  459.     return gs_setdotorientation(igs);
  460. }
  461.  
  462. /* - .dotorientation - */
  463. private int
  464. zdotorientation(i_ctx_t *i_ctx_p)
  465. {
  466.     return gs_dotorientation(igs);
  467. }
  468.  
  469. /* <bool> .setlimitclamp - */
  470. private int
  471. zsetlimitclamp(i_ctx_t *i_ctx_p)
  472. {
  473.     return zset_bool(i_ctx_p, gs_setlimitclamp);
  474. }
  475.  
  476. /* - .currentlimitclamp <bool> */
  477. private int
  478. zcurrentlimitclamp(i_ctx_t *i_ctx_p)
  479. {
  480.     return zcurrent_bool(i_ctx_p, gs_currentlimitclamp);
  481. }
  482.  
  483. /* ------ Initialization procedure ------ */
  484.  
  485. /* We need to split the table because of the 16-element limit. */
  486. const op_def zgstate1_op_defs[] = {
  487.     {"0.currentaccuratecurves", zcurrentaccuratecurves},
  488.     {"0.currentcurvejoin", zcurrentcurvejoin},
  489.     {"0currentdash", zcurrentdash},
  490.     {"0.currentdashadapt", zcurrentdashadapt},
  491.     {"0.currentdotlength", zcurrentdotlength},
  492.     {"0.currentfilladjust2", zcurrentfilladjust2},
  493.     {"0currentflat", zcurrentflat},
  494.     {"0.currentlimitclamp", zcurrentlimitclamp},
  495.     {"0currentlinecap", zcurrentlinecap},
  496.     {"0currentlinejoin", zcurrentlinejoin},
  497.     {"0currentlinewidth", zcurrentlinewidth},
  498.     {"0currentmiterlimit", zcurrentmiterlimit},
  499.     {"0.dotorientation", zdotorientation},
  500.     {"0grestore", zgrestore},
  501.     {"0grestoreall", zgrestoreall},
  502.     op_def_end(0)
  503. };
  504. const op_def zgstate2_op_defs[] = {
  505.     {"0gsave", zgsave},
  506.     {"0initgraphics", zinitgraphics},
  507.     {"1.setaccuratecurves", zsetaccuratecurves},
  508.     {"1.setcurvejoin", zsetcurvejoin},
  509.     {"2setdash", zsetdash},
  510.     {"1.setdashadapt", zsetdashadapt},
  511.     {"2.setdotlength", zsetdotlength},
  512.     {"0.setdotorientation", zsetdotorientation},
  513.     {"2.setfilladjust2", zsetfilladjust2},
  514.     {"1.setlimitclamp", zsetlimitclamp},
  515.     {"1setflat", zsetflat},
  516.     {"1.setlinecap", zsetlinecap},
  517.     {"1.setlinejoin", zsetlinejoin},
  518.     {"1setlinewidth", zsetlinewidth},
  519.     {"1setmiterlimit", zsetmiterlimit},
  520.     op_def_end(0)
  521. };
  522.  
  523. /* ------ Internal routines ------ */
  524.  
  525. /* Allocate the interpreter's part of a graphics state. */
  526. private void *
  527. gs_istate_alloc(gs_memory_t * mem)
  528. {
  529.     return gs_alloc_struct(mem, int_gstate, &st_int_gstate, "int_gsave");
  530. }
  531.  
  532. /* Copy the interpreter's part of a graphics state. */
  533. private int
  534. gs_istate_copy(void *to, const void *from)
  535. {
  536.     *(int_gstate *) to = *(const int_gstate *)from;
  537.     return 0;
  538. }
  539.  
  540. /* Free the interpreter's part of a graphics state. */
  541. private void
  542. gs_istate_free(void *old, gs_memory_t * mem)
  543. {
  544.     gs_free_object(mem, old, "int_grestore");
  545. }
  546.